﻿/*
    File name:          ManageUsersViewModel
    File type:          class
    Author:             Mads Skipper Pedersen 07299
    Creation date:      03-05-2011
    Last modified:      18-05-2011
    Last modified by:   Mads Skipper Pedersen 07299
    Description:        The ViewModel for the Manage Users View
                        Used to Add/Edit/Delete Users
                        Only visible to users with Admin rights.
*/

using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows.Input;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using i4pro_gruppe_d.Database;
using i4pro_gruppe_d.Types;
using System;

namespace AdminManageUsers.ViewModel
{
    class ManageUsersViewModel : ViewModelBase
    {
        #region Members
        private BackgroundWorker bgw;
        private AbstractDatabase db;
        private string OldUserName;
        private List<User> templist;
        #endregion

        #region Propertys

        public ObservableCollection<User> UserList
        {
            get;
            set;
        }
        public ObservableCollection<string> UserLevelList
        {
            get;
            set;
        }

        private int selectedUserIndex;
        public int SelectedUserIndex
        {
            get
            {
                return selectedUserIndex;
            }
            set
            {
                selectedUserIndex = value;
                RaisePropertyChanged("SelectedUserIndex");
            }
        }

        private string selectedUserName;
        public string SelectedUserName
        {
            get
            {
                return selectedUserName;
            }
            set
            {
                selectedUserName = value;
                RaisePropertyChanged("SelectedUserName");
            }
        }

        private string selectedUserPassword;
        public string SelectedUserPassword
        {
            get
            {
                return selectedUserPassword;
            }
            set
            {
                selectedUserPassword = value;
                RaisePropertyChanged("SelectedUserPassword");
            }
        }

        private int selectedUserLevel;
        public int SelectedUserLevel
        {
            get
            {
                return selectedUserLevel;
            }
            set
            {
                selectedUserLevel = value;
                RaisePropertyChanged("SelectedUserLevel");
            }
        }

        #endregion

        #region Constructor
        public ManageUsersViewModel()
        {
            UserLevelList = new ObservableCollection<string>() {"Opperator", "Technician", "Admin"};
            UserList = new ObservableCollection<User>();
            templist = new List<User>();
            GetUserList();
        }
        #endregion

        #region Commands
        #region SelectionChanged Command
        public ICommand SelectionChanged_Cmd
        {
            get { return new RelayCommand(SelectionChangedExecute); }
        }

        private void SelectionChangedExecute()
        {
            if (selectedUserIndex != -1)
            {
                SelectedUserName = UserList[SelectedUserIndex].UserID;
                OldUserName = selectedUserName;
                SelectedUserPassword = "Hidden!";
                SelectedUserLevel = UserList[selectedUserIndex].UserType;
            }
            else
            {
                SelectedUserName = "Select user";
                SelectedUserPassword = "Select user";
                SelectedUserLevel = 0;
            }
        }
        #endregion
        #region Commit user changes Command
        /// <summary>
        /// Updates the user information in the database using a backgroundworker
        /// </summary>
        public ICommand Commit_Cmd
        {
            get { return new RelayCommand(CommitExecute); }
        }
        
        private void CommitExecute()
        {
            UpdateUser();
        }
        #endregion
        #region Add User Command
        /// <summary>
        /// Adds the user to the database with the typed in username
        /// and password and sets the access level.
        /// </summary>
        public ICommand AddUser_Cmd
        {
            get { return new RelayCommand(AddUserExecute); }
        }

        private void AddUserExecute()
        {
            AddUser();
        }
        #endregion
        /// <summary>
        /// Removes the selected user from the database
        /// </summary>
        #region Delete User Command
        public ICommand DeleteUser_Cmd
        {
            get { return new RelayCommand(DeleteUserExecute); }
        }

        private void DeleteUserExecute()
        {
            DeleteUser();
        }
        #endregion
        #endregion

        #region Methods
        private void GetUserList()
        {
            UserList.Clear();
            bgw = new BackgroundWorker();
            bgw.DoWork += Bgw_GetUsers_DoWork;
            bgw.RunWorkerCompleted += Bgw_GetUsers_Complete;
            bgw.RunWorkerAsync();
        }
        private void AddUser()
        {
            bgw = new BackgroundWorker();
            bgw.DoWork += Bgw_AddUser_DoWork;
            bgw.RunWorkerCompleted += Bgw_AddUser_Complete;
            bgw.RunWorkerAsync();
        }
        private void UpdateUser()
        {
            bgw = new BackgroundWorker();
            bgw.DoWork += Bgw_UpdateUser_DoWork;
            bgw.RunWorkerCompleted += Bgw_UpdateUser_Complete;
            bgw.RunWorkerAsync();
        }
        private void DeleteUser()
        {
            bgw = new BackgroundWorker();
            bgw.DoWork += Bgw_DeleteUser_DoWork;
            bgw.RunWorkerCompleted += Bgw_DeleteUser_Complete;
            bgw.RunWorkerAsync();
        }
        #endregion

        #region Background Worker
        private void Bgw_GetUsers_DoWork(Object sender, DoWorkEventArgs e)
        {
            db = AbstractDatabase.Instance;
            templist = db.getUserList();
        }
        private void Bgw_GetUsers_Complete(Object sender, RunWorkerCompletedEventArgs e)
        {
            foreach (var user in templist)
            {
                UserList.Add(user);
            }
            if (templist.Count != 0)
                SelectionChangedExecute();
        }
        private void Bgw_AddUser_DoWork(Object sender, DoWorkEventArgs e)
        {
            db = AbstractDatabase.Instance;
            db.NewUser(new User(SelectedUserName, SelectedUserPassword, SelectedUserLevel));

            //Upadte to eventLog
            EventLog myEvent = new EventLog();
            myEvent.LogEntry = myEvent.GetLogDescription((int)DescriptionType.UserCommand) + selectedUserName + " created.";
            myEvent.LogTime = DateTime.Now;
            myEvent.LogType = (int)Codes.Command;
            db.WriteEventLog(myEvent);
        }
        private void Bgw_AddUser_Complete(Object sender, RunWorkerCompletedEventArgs e)
        {
            GetUserList();
        }
        private void Bgw_UpdateUser_DoWork(Object sender, DoWorkEventArgs e)
        {
            string pass = "";
            db = AbstractDatabase.Instance;

            if (selectedUserPassword != "Hidden!")
                pass = selectedUserPassword;

            db.UpdateUser(new User(SelectedUserName, pass, SelectedUserLevel), OldUserName);

            //Upadte to eventLog
            EventLog myEvent = new EventLog();
            myEvent.LogEntry = myEvent.GetLogDescription((int)DescriptionType.UserCommand) + OldUserName + " updated.";
            myEvent.LogTime = DateTime.Now;
            myEvent.LogType = (int)Codes.Command;
            db.WriteEventLog(myEvent);
        }
        private void Bgw_UpdateUser_Complete(Object sender, RunWorkerCompletedEventArgs e)
        {
            GetUserList();
        }
        private void Bgw_DeleteUser_DoWork(Object sender, DoWorkEventArgs e)
        {
            db = AbstractDatabase.Instance;
            db.DeleteUser(UserList[selectedUserIndex]);

            //Upadte to eventLog
            EventLog myEvent = new EventLog();
            myEvent.LogEntry = myEvent.GetLogDescription((int)DescriptionType.UserCommand) + UserList[selectedUserIndex].UserID + " deleted.";
            myEvent.LogTime = DateTime.Now;
            myEvent.LogType = (int)Codes.Command;
            db.WriteEventLog(myEvent);
        }
        private void Bgw_DeleteUser_Complete(Object sender, RunWorkerCompletedEventArgs e)
        {
            GetUserList();
        }
        #endregion
    }
}
